using System;
using System.IO;
using System.Reflection;
using EnvDTE80;
using Microsoft.VisualStudio.TeamFoundation.VersionControl;
using Microsoft.TeamFoundation.VersionControl.Client;
using TeamReview.Services;

namespace TeamReview.Command
{
    /// <summary>
    /// Establishes the Template Method Pattern for showing a TeamReview dialog.
    /// </summary>
    /// <remarks>
    /// The aglorithm for the pattern is to defer the dialog to be shown to implementors of this 
    /// abstract class, but to only invoke that step in the algorithim if TeamReview should
    /// be "active" based on the current state of the IDE and open solution.
    /// </remarks>
	public abstract class ShowFormCommand
	{
        protected readonly DTE2 shellDTE;

        protected ShowFormCommand()
        {
        }

        protected ShowFormCommand(DTE2 visualStudio)
        {
            if (visualStudio == null)
                throw new NullReferenceException();

            shellDTE = visualStudio;
        }

        /// <summary>
        /// Determines if TeamReview should be active.
        /// </summary>
        /// <remarks>
        /// Requires that the current Visual Studio Solution is a TFS "Bound" solution, and the 
        /// VSTS Project that it is bound to has the Code Review Replay Work Item Type
        /// </remarks>
        /// <returns></returns>
        protected virtual bool GetEnabledState()
        {
            if (!TFSService.IsTFSProject)
                return false;

            return TFSService.GetAvailableTeamWorkItemTypes.Contains(Constants.CODE_REVIEW_ITEM_TYPE);
        }

        /// <summary>
        /// Invokes <see cref="ShowForm"/> 
        /// In inherited members wiil be used to control if TeamReview can be active, otherwise will show 
        /// directions on how to make TeamReview active
        /// </summary>
        /// <remarks>
        /// The algorithim of the Template Method Pattern. The deferred step is <see cref="ShowForm"/>
        /// </remarks>
		public virtual void Execute()
		{
            if (!GetEnabledState())
            {
                ShowDirectionsFormCommand directions = new ShowDirectionsFormCommand();
                directions.Execute();
                directions.Shutdown();
                return;
            }

			ShowForm();
		}

       public abstract void Shutdown();

        /// <summary>
        /// Shows a Visual Studio Form/Dialog
        /// </summary>
        /// <remarks>This is the deferred step in the Teamplate Method Pattern.</remarks>
		protected abstract void ShowForm();
	}
}
